package com.iwhalecloud.citybrain.flow.platform.manager.application.service.impl.task;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

import com.iwhalecloud.citybrain.flow.platform.manager.application.service.impl.MultiExecutionCompletedProcessor;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.model.FlowMultiInstanceTaskTraceVo;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.repository.FlowMultiInstanceTaskTraceRepository;
import com.iwhalecloud.citybrain.flow.platform.manager.application.common.enums.TaskLinkStatusEnum;
import com.iwhalecloud.citybrain.flow.platform.manager.application.service.CustomEventHandler;
import com.iwhalecloud.citybrain.flow.platform.manager.application.utils.SpringUtils;
import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.common.api.delegate.event.FlowableEngineEventType;
import org.flowable.engine.common.api.delegate.event.FlowableEvent;
import org.flowable.engine.common.api.delegate.event.FlowableEventType;
import org.flowable.engine.delegate.event.FlowableMultiInstanceActivityCompletedEvent;
import org.flowable.engine.impl.persistence.entity.ExecutionEntity;
import org.flowable.engine.impl.util.CommandContextUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;

/**
 * @author lilh
 * @date 2019-09-20 09:18
 */
@Slf4j
@Component
public class MultiInstanceActivityCompletedHandler implements CustomEventHandler {

    @Lazy
    @Autowired(required = false)
    private List<MultiExecutionCompletedProcessor> multiExecutionCompletedProcessorList = new ArrayList<>();

    @Override
    public FlowableEventType getEventType() {
        return FlowableEngineEventType.MULTI_INSTANCE_ACTIVITY_COMPLETED_WITH_CONDITION;
    }

    @Override
    public void handle(FlowableEvent event) throws Exception {
        if (!(event instanceof FlowableMultiInstanceActivityCompletedEvent)) {
            return;
        }
        FlowableMultiInstanceActivityCompletedEvent multiInstanceActivityCompletedEvent = (FlowableMultiInstanceActivityCompletedEvent) event;
        //更新多实例跟踪表
        updateMultiInstanceTaskTrace(multiInstanceActivityCompletedEvent);
        //System.out.println("会签节点结束");

        ExecutionEntity executionEntity = CommandContextUtil.getExecutionEntityManager().findById(multiInstanceActivityCompletedEvent.getExecutionId());
        if (Objects.nonNull(executionEntity)){
            executeMultiExecutionCompletedProcessor(executionEntity);
        }
    }

    private void executeMultiExecutionCompletedProcessor(ExecutionEntity executionEntity) throws Exception {
        for (MultiExecutionCompletedProcessor multiExecutionCompletedProcessor : multiExecutionCompletedProcessorList) {
            try {
                multiExecutionCompletedProcessor.process(executionEntity);
            } catch (Throwable e) {
                log.error("executeMultiExecutionCompletedProcessor error:",e);
                throw e;
            }
        }
    }

    private void updateMultiInstanceTaskTrace(FlowableMultiInstanceActivityCompletedEvent multiInstanceActivityCompletedEvent) {
        FlowMultiInstanceTaskTraceRepository multiInstanceTaskTraceService = SpringUtils.getBean(FlowMultiInstanceTaskTraceRepository.class);
        FlowMultiInstanceTaskTraceVo multiInstanceRoot = multiInstanceTaskTraceService.getByRootExecutionId(multiInstanceActivityCompletedEvent.getExecutionId());
        multiInstanceRoot.setNumOfCompletedInstances(multiInstanceActivityCompletedEvent.getNumberOfCompletedInstances());
        multiInstanceRoot.setNumOfActiveInstances(multiInstanceActivityCompletedEvent.getNumberOfActiveInstances());
        multiInstanceRoot.setLinkStatus(TaskLinkStatusEnum.DONE.getCode());
        multiInstanceRoot.setUpdateTime(new Date());
        multiInstanceTaskTraceService.updateMultiInstanceTaskTrace(multiInstanceRoot);
    }
}
